/** \file gu_render_context.cpp */

#include "gu_render_context.h"
#include "gu_shader_parser.h"

#include "gr_algorithms.h"

#include<algorithm>
#include<sstream>
#include<cassert>

namespace gu {
namespace state {

Data getData(Setting type)
{
    Data d;
    d.type = type;
    return d;
}

Data getData(Setting type, gr::Float4 f4)
{
    Data d;
    d.type = type;
    d.f4 = f4;
    return d;
}

Data getData(Setting type, float f)
{
    Data d;
    d.type = type;
    d.f = f;
    return d;
}

/** Remove instance of d from sequence */
void remove(DataSequence& s, const Data& d)
{
    s.remove_if([&d](const Data& a)->bool{return a.type == d.type;});
}

/** Add instance of d to sequence. Replace duplicates, if exists. */
void add(DataSequence& s, Data& d)
{
    remove(s, d);
    s.push_back(d);
}


extern void apply_glsl330(DataSequence& data);


ApplyFunction getApply(ShaderDialect dialect)
{
    switch(dialect)
    {
    case GLSL_330: return apply_glsl330;
    default: return [](DataSequence& s){assert(!"Invalid apply.");};
    }
}

#if 0
std::string toString(std::vector<Data>& data)
{
    std::ostringstream out;

    for(auto d = data.begin(); d != data.end(); ++d)
    {
#define CASE(state_, fun_) case state_: fun_; break
        switch(d->type)
        {
            CASE(CLEAR_COLOR, );
            CASE(CLEAR_DEPTH, );

            CASE(BUFFER_ACTIVATE_COLOR, );
            CASE(BUFFER_ACTIVATE_DEPTH, )
            CASE(BUFFER_ACTIVATE_STENCIL, );
        
            CASE(BUFFER_CLEAR_COLOR, );
            CASE(BUFFER_CLEAR_DEPTH, );

            default:
            {
                assert(!"Type error");
                break;
            }
        }
#undef CASE
    }
    return out.str();
}
#endif
}
}
